package org.code.boot.service.boot.impl;

import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import cn.hutool.core.collection.CollUtil;
import java.util.stream.Collectors;
import org.code.boot.common.exception.ServiceException;
import org.code.boot.domain.boot.BizOrderHistory;
import org.code.boot.service.boot.IBizOrderHistoryService;
import org.code.boot.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.code.boot.mapper.boot.BizTrainOrderMapper;
import org.code.boot.domain.boot.BizTrainOrder;
import org.code.boot.service.boot.IBizTrainOrderService;
import org.code.boot.service.boot.IBizTrainSeatConfigService;
import org.code.boot.domain.boot.BizTrainSeatConfig;

/**
 * 火车票订单Service业务层处理
 * 
 * @author coder
 * @date 2025-08-28
 */
@Service
public class BizTrainOrderServiceImpl implements IBizTrainOrderService 
{
    @Autowired
    private BizTrainOrderMapper bizTrainOrderMapper;

    @Autowired
    private IBizOrderHistoryService bizOrderHistoryService;

    @Autowired
    private IBizTrainSeatConfigService bizTrainSeatConfigService;


    /**
     * 查询火车票订单
     * 
     * @param trainOrderId 火车票订单主键
     * @return 火车票订单
     */
    @Override
    public BizTrainOrder selectBizTrainOrderByTrainOrderId(Long trainOrderId)
    {
        return bizTrainOrderMapper.selectBizTrainOrderByTrainOrderId(trainOrderId);
    }

    /**
     * 查询火车票订单列表
     * 
     * @param bizTrainOrder 火车票订单
     * @return 火车票订单
     */
    @Override
    public List<BizTrainOrder> selectBizTrainOrderList(BizTrainOrder bizTrainOrder)
    {
        return bizTrainOrderMapper.selectBizTrainOrderList(bizTrainOrder);
    }

    /**
     * 新增火车票订单
     * 
     * @param bizTrainOrder 火车票订单
     * @return 结果
     */
    @Override
    @Transactional
    public int insertBizTrainOrder(BizTrainOrder bizTrainOrder)
    {
        bizTrainOrder.setCreateTime(DateUtils.getNowDate());
        
        // 插入订单
        int result = bizTrainOrderMapper.insertBizTrainOrder(bizTrainOrder);
        
        // 更新座位库存 - 减少可用座位数
        if (result > 0 && bizTrainOrder.getTrainId() != null) {
            updateSeatInventory(bizTrainOrder.getTrainId(), bizTrainOrder.getSeatNumber());
        }
        
        return result;
    }

    /**
     * 修改火车票订单
     * 
     * @param bizTrainOrder 火车票订单
     * @return 结果
     */
    @Override
    public int updateBizTrainOrder(BizTrainOrder bizTrainOrder)
    {
        bizTrainOrder.setUpdateTime(DateUtils.getNowDate());
        return bizTrainOrderMapper.updateBizTrainOrder(bizTrainOrder);
    }

    /**
     * 批量删除火车票订单
     * 
     * @param trainOrderIds 需要删除的火车票订单主键
     * @return 结果
     */
    @Override
    public int deleteBizTrainOrderByTrainOrderIds(Long[] trainOrderIds)
    {
        // 检查数据表是否被其他表引用
        List<Long> idList = Arrays.asList(trainOrderIds);
        if (isDataTableReferenced(idList))
        {
            throw new ServiceException("该火车票订单中有数据正在被其他表引用，无法删除");
        }
        return bizTrainOrderMapper.deleteBizTrainOrderByTrainOrderIds(trainOrderIds);
    }

    /**
     * 删除火车票订单信息
     * 
     * @param trainOrderId 火车票订单主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteBizTrainOrderByTrainOrderId(Long trainOrderId)
    {
        // 检查数据表是否被其他表引用
        List<Long> idList = Arrays.asList(trainOrderId);
        if (isDataTableReferenced(idList))
        {
            throw new ServiceException("该火车票订单正在被其他数据引用，无法删除");
        }
        
        // 先获取订单信息用于恢复库存
        BizTrainOrder order = bizTrainOrderMapper.selectBizTrainOrderByTrainOrderId(trainOrderId);
        
        // 删除订单
        int result = bizTrainOrderMapper.deleteBizTrainOrderByTrainOrderId(trainOrderId);
        
        // 恢复座位库存 - 增加可用座位数
        if (result > 0 && order != null) {
            restoreSeatInventory(order.getTrainId(), order.getSeatNumber());
        }
        
        return result;
    }
    /**
     * 获得火车票订单列表
     *
     * @param ids 火车票订单编号数组
     * @return 火车票订单列表
     */
    @Override
    public List<BizTrainOrder> getBizTrainOrderList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        return bizTrainOrderMapper.selectBizTrainOrderListByIds(ids);
    }

    /**
     * 根据用户IDID列表统计火车票订单数量
     *
     * @param userIds 用户IDID数组
     * @return 火车票订单数量
     */
    @Override
    public Long countByUserIds(Collection<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return 0L;
        }
        return bizTrainOrderMapper.countByUserIds(userIds);
    }

    /**
     * 根据火车IDID列表统计火车票订单数量
     *
     * @param trainIds 火车IDID数组
     * @return 火车票订单数量
     */
    @Override
    public Long countByTrainIds(Collection<Long> trainIds) {
        if (CollUtil.isEmpty(trainIds)) {
            return 0L;
        }
        return bizTrainOrderMapper.countByTrainIds(trainIds);
    }

    @Override
    public List<String> getSeatNumbersByTrainId(Long trainId) {
        return bizTrainOrderMapper.selectSeatNumbersByTrainId(trainId);
    }

    
    /**
     * 检查数据表是否被其他表引用
     * 
     * @param ids 火车票订单主键列表
     * @return 是否被引用
     */
    private boolean isDataTableReferenced(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return false;
        }
        
        // 检查引用此数据表的其他表
        // 检查 BizOrderHistory 表中是否有引用当前数据的记录
        Long count1 = bizOrderHistoryService.countByOrderIds(ids);
        if (count1 != null && count1 > 0) {
            return true; // BizOrderHistory 表中存在引用记录
        }

        return false;
    }
    
    /**
     * 更新座位库存
     * 
     * @param trainId 火车ID
     * @param seatNumber 座位号
     */
    private void updateSeatInventory(Long trainId, String seatNumber) {
        if (trainId == null || seatNumber == null || seatNumber.isEmpty()) {
            return;
        }
        
        // 从座位号中提取座位等级信息 (假设座位号格式为: 车厢号+座位类型+座位号，如"01A001")
        // 这里简化处理，假设根据座位号格式可以确定座位等级
        String seatClass = determineSeatClass(seatNumber);
        
        // 获取该火车的座位配置
        List<BizTrainSeatConfig> seatConfigs = bizTrainSeatConfigService.selectBizTrainSeatConfigByTrainId(trainId);
        
        for (BizTrainSeatConfig config : seatConfigs) {
            // 找到对应座位等级的配置并减少库存
            if (seatClass.equals(config.getSeatClass()) && config.getAvailableSeats() > 0) {
                config.setAvailableSeats(config.getAvailableSeats() - 1);
                bizTrainSeatConfigService.updateBizTrainSeatConfig(config);
                break;
            }
        }
    }
    
    /**
     * 根据座位号确定座位等级
     * 
     * @param seatNumber 座位号
     * @return 座位等级
     */
    private String determineSeatClass(String seatNumber) {
        // 简化逻辑：根据座位号的字符判断座位等级
        if (seatNumber.contains("A") || seatNumber.contains("B")) {
            return "first_class"; // 一等座
        } else if (seatNumber.contains("C") || seatNumber.contains("D")) {
            return "second_class"; // 二等座
        } else if (seatNumber.contains("F")) {
            return "business_class"; // 商务座
        }
        // 默认返回二等座
        return "second_class";
    }
    
    /**
     * 恢复座位库存
     * 
     * @param trainId 火车ID
     * @param seatNumber 座位号
     */
    private void restoreSeatInventory(Long trainId, String seatNumber) {
        if (trainId == null || seatNumber == null || seatNumber.isEmpty()) {
            return;
        }
        
        // 从座位号中提取座位等级信息
        String seatClass = determineSeatClass(seatNumber);
        
        // 获取该火车的座位配置
        List<BizTrainSeatConfig> seatConfigs = bizTrainSeatConfigService.selectBizTrainSeatConfigByTrainId(trainId);
        
        for (BizTrainSeatConfig config : seatConfigs) {
            // 找到对应座位等级的配置并增加库存
            if (seatClass.equals(config.getSeatClass())) {
                config.setAvailableSeats(config.getAvailableSeats() + 1);
                bizTrainSeatConfigService.updateBizTrainSeatConfig(config);
                break;
            }
        }
    }
}
